package TAIC.IPLM;
import java.io.*;
import java.util.*; 

public class CodeBookGen {
	static public void main ( String str[] 	) {
		if (  str.length < 2 ) {
			System.out.println ( "please input the config file and desFile (train.mat)") ;
			return ;
		}
		( new CodeBookGen()).generateCodeBook(str [ 0 ], str[ 1 ]);
	}
	
	public void generateCodeBook ( String configFile , String dstFile ) {
		try{
			Scanner configScanner = new Scanner ( new File ( configFile )) ; 
			Node [] datasets = new Node [ configScanner.nextInt() ];
			int totalVec = 0 ;
			int desiredVec = configScanner.nextInt() ; configScanner.nextLine () ; 
			for ( int i = 0 ; i < datasets.length ; i ++ ){
				datasets [ i ] = new Node () ; 
				datasets [ i ].path = configScanner.nextLine().trim() + "\\";
				File tempfile = new File ( datasets[i].path) ; 
				if ( !tempfile.exists() ) {
					System.out.println ( "Folder " + datasets[i].path + " does not exist") ;
					return ; 
				}
				Scanner imageScanner = new Scanner ( new File ( datasets[ i ].path + "ImageCorpus.txt"));
				while( imageScanner.hasNextInt () ) {
					imageScanner.nextInt() ; imageScanner.nextInt() ;
					File iFile = new File ( imageScanner.nextLine().trim() +".sift" );
					if ( !iFile.exists() ) continue ; 
					Scanner tempScanner = new Scanner ( iFile ) ;
					int vecs = tempScanner.nextInt() ; 
					datasets[ i ].oriSize +=  vecs;
					tempScanner.close() ;
				}
				totalVec += datasets[ i ].oriSize ;
				imageScanner.close() ; 
			}
			
			Vector < String >codeBook = new Vector < String > () ;  
			double ratio = (double)desiredVec / totalVec ;
			if ( ratio > 1 ) ratio = 1.0 ;
			for ( int i = 0 ; i < datasets.length ; i ++ ) {
				Scanner scanner = new Scanner ( new File ( datasets[ i ].path + "ImageCorpus.txt"));
				while ( scanner.hasNextInt() ) {
					scanner.nextInt() ;scanner.nextInt() ;
					File iFile = new File ( scanner.nextLine().trim() +".sift" );
					if ( !iFile.exists() ) continue ; 
					Scanner imageScanner = new  Scanner ( iFile ) ;
					int vecsize = imageScanner.nextInt() ;   //   total vectors in image
					//System.out.println ( vecsize ) ; 
					imageScanner.nextLine(); 
					String [] str = new String [ vecsize ] ; 
					boolean [] used = new boolean [ vecsize ]; 
					int extsize = toInt ( ratio * vecsize ) ;  // number of vector to random extract 
					for ( int j = 0 ; j < vecsize ; j ++ ) str [ j ] = imageScanner.nextLine() ;
					for ( int j = 0;  j < extsize ; j ++ ) {
						int temp = random.nextInt( vecsize ) ;
						if ( !used [ temp ]) codeBook.add( str [ temp ]) ;
						else j -- ;
						used [ temp ] = true ;
					}
					imageScanner.close () ; 
				}
			}
			
			PrintStream fout = new PrintStream ( new File ( dstFile ) ) ;
			fout.println ( codeBook.size() + " 128" ) ;
			for ( String s : codeBook ) fout.println ( s ) ;
			fout.close() ; 
		}
		catch ( Exception e ){
			e.printStackTrace() ;
			return ; 
		}
	}
	
	
	int toInt ( double d ){
		return Math.round((float)Math.floor(d)) ;
	}
	
	public class Node  {
		String path ;
		int oriSize ;
		int extSize ; 
	}
		
	static Random random = new Random () ;
}
